package com.sojson.util.encrypt.bothway.imparity.sm2;

import com.sojson.util.Util;
import com.sojson.util.encrypt.bothway.imparity.bean.CustomKeyPair;
import com.sojson.util.encrypt.bothway.imparity.sm2.impl.encrypt.Sm2UtilImpl;
import com.sojson.util.encrypt.bothway.imparity.sm2.impl.sign.Sm2SignUtilImpl;

/**
 * Sms2双向非对称加解密工具类
 * 
 * @author liu
 * @date 2020-09-04
 */
public class Sm2Util {

    private static final ISm2Util SM2 = Sm2UtilImpl.getInstances();
    private static final ISm2SignUtil SIGN = Sm2SignUtilImpl.getInstances();

    /**
     * 加密
     * 
     * @param data      内容
     * @param publicKey 公钥
     * @return
     * @throws Exception 
     */
    public static String encrypt(String data, String publicKey) throws Exception {
        return SM2.encrypt(data, publicKey);
    }

    /**
     * 加密
     * 
     * @param data      内容
     * @param publicKey 公钥
     * @return
     * @throws Exception 
     */
    public static byte[] encrypt(byte[] data, String publicKey) throws Exception {
        return SM2.encrypt(data, publicKey);
    }

    /**
     * 加密
     * 
     * @param data      内容
     * @param publicKey 公钥
     * @return
     * @throws Exception 
     */
    public static byte[] encryptToByte(String data, String publicKey) throws Exception {
        return SM2.encryptToByte(data, publicKey);
    }

    /**
     * 加密
     * 
     * @param data      内容
     * @param publicKey 公钥
     * @return
     * @throws Exception 
     */
    public static String encryptToStr(byte[] data, String publicKey) throws Exception {
        return SM2.encryptToStr(data, publicKey);
    }

    /**
     * 解密
     * 
     * @param data          内容
     * @param privateKey    私钥
     * @return
     * @throws Exception 
     */
    public static String decrypt(String data, String privateKey) throws Exception {
        return SM2.decrypt(data, privateKey);
    }

    /**
     * 解密
     * 
     * @param data          内容
     * @param privateKey    私钥
     * @return
     * @throws Exception 
     */
    public static byte[] decrypt(byte[] data, String privateKey) throws Exception {
        return SM2.decrypt(data, privateKey);
    }

    /**
     * 解密
     * 
     * @param data          内容
     * @param privateKey    私钥
     * @return
     * @throws Exception 
     */
    public static byte[] decryptToByte(String data, String privateKey) throws Exception {
        return SM2.decryptToByte(data, privateKey);
    }

    /**
     * 解密
     * 
     * @param data          内容
     * @param privateKey    私钥
     * @return
     * @throws Exception 
     */
    public static String decryptToStr(byte[] data, String privateKey) throws Exception {
        return SM2.decryptToStr(data, privateKey);
    }

    /**
    * 签名
    * @param data 数据
    * @return 签名
    */
    public static String sign(String data, String privateKey) throws Exception {
        return SIGN.sign(data, privateKey);
    }

    /**
    * 签名
    * @param data 数据
    * @return 签名
    */
    public static byte[] signToByte(String data, String privateKey) throws Exception {
        return SIGN.signToByte(data, privateKey);
    }

    /**
    * 签名
    * @param data 数据
    * @return 签名
    */
    public static String signToStr(byte[] data, String privateKey) throws Exception {
        return SIGN.signToStr(data, privateKey);
    }

    /**
    * 签名
    * @param data 数据
    * @return 签名
    */
    public static byte[] sign(byte[] data, String privateKey) throws Exception {
        return SIGN.sign(data, privateKey);
    }

    /**
     * 用公钥检验数字签名的合法性
     * @param data      数据
     * @param sign      签名
     * @param publicKey 公钥
     * @return 是否验证通过
     */
    public static boolean verify(String data, String sign, String publicKey) throws Exception {
        return SIGN.verify(data, sign, publicKey);
    }

    /**
     * 用公钥检验数字签名的合法性
     * @param data      数据
     * @param sign      签名
     * @param publicKey 公钥
     * @return 是否验证通过
     */
    public static boolean verify(byte[] data, byte[] sign, String publicKey) throws Exception {
        return SIGN.verify(data, sign, publicKey);
    }

    /**
     * 加密
     * 
     * @param data      内容
     * @param publicKey 公钥
     * @return
     * @throws Exception 
     */
    public static String encryptContentToStr(byte[] data) {
        return Util.byteToHex(data);
    }

    /**
     * 解密
     * 
     * @param data          内容
     * @param privateKey    私钥
     * @return
     * @throws Exception 
     */
    public static byte[] decryptContentToByte(String data) {
        return Util.hexToByte(data);
    }

    /**
     * 获得公私钥对
     * @return 
     * @throws Exception 
     */
    public static CustomKeyPair generateKeyPair() throws Exception {
        return SM2.generateKeyPair();
    }

    // public static void main(String[] args) throws Exception {
    // String m =
    // "哈哈哈，&*&…………&、、//\\!@#$%^&*()物品woyebuzhidaowozijiqiaodesha!@#$%^&*())))))ooooooooppppppppppppppppppplllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkffffffffffffffffffffffffffffffffffffff";
    // byte[] bytes = m.getBytes();
    // CustomKeyPair keyPair = null;
    // String publicKey = null;
    // String privateKey = null;
    //
    // keyPair = Sm2Util.generateKeyPair();
    // publicKey = keyPair.getPublicKeyStr();
    // privateKey = keyPair.getPrivateKeyStr();
    // System.out.println("公钥: " + publicKey);
    // System.out.println("私钥: " + privateKey);
    //
    // String encrypt = null;
    // byte[] encrypt2 = null;
    // String decrypt2 = null;
    //
    // encrypt = Sm2Util.encrypt(m, publicKey);
    // encrypt2 = Sm2Util.encrypt(bytes, publicKey);
    // byte[] encryptToByte = Sm2Util.encryptToByte(m, publicKey);
    // String encryptToStr = Sm2Util.encryptToStr(bytes, publicKey);
    // System.out.println("加密: " + encrypt);
    // System.out.println("加密: " + new String(encrypt2));
    // System.out.println("加密: " + new String(encryptToByte));
    // System.out.println("加密: " + encryptToStr);
    // decrypt2 = Sm2Util.decrypt(encrypt, privateKey);
    // byte[] decrypt3 = Sm2Util.decrypt(encrypt2, privateKey);
    // String decryptToStr = Sm2Util.decryptToStr(encryptToByte, privateKey);
    // byte[] decryptToByte = Sm2Util.decryptToByte(encryptToStr, privateKey);
    // System.out.println("解密: " + decrypt2);
    // System.out.println("解密: " + new String(decrypt3));
    // System.out.println("解密: " + decryptToStr);
    // System.out.println("解密: " + new String(decryptToByte));
    // System.out.println("================================================");
    // System.out.println("================================================");
    // System.out.println("================================================");
    //
    // int size = 100;
    // long currentTimeMillis = System.currentTimeMillis();
    // for (int i = 0; i < size; i++) {
    // encrypt = Sm2Util.encrypt(m, publicKey);
    // decrypt2 = Sm2Util.decrypt(encrypt, privateKey);
    // if (!m.equals(decrypt2)) {
    // System.out.println(decrypt2);
    // }
    // }
    // long currentTimeMillis2 = System.currentTimeMillis();
    // System.out.println(currentTimeMillis2 - currentTimeMillis);
    //
    // System.out.println("================================================");
    // System.out.println("================================================");
    // System.out.println("================================================");
    //
    // // 生成签名
    // String signature = Sm2Util.sign(m, keyPair.getPrivateKeyStr());
    // byte[] signToByte = Sm2Util.signToByte(m, privateKey);
    // String signToStr = Sm2Util.signToStr(bytes, keyPair.getPrivateKeyStr());
    // byte[] sign = Sm2Util.sign(bytes, privateKey);
    // System.out.println("签名: " + new String(signature));
    // System.out.println("签名: " + new String(signToByte));
    // System.out.println("签名: " + new String(signToStr));
    // System.out.println("签名: " + new String(sign));
    // // 验签
    // boolean verify = Sm2Util.verify(m, signature, keyPair.getPublicKeyStr());
    // boolean verify2 = Sm2Util.verify(bytes, signToByte, keyPair.getPublicKeyStr());
    // boolean verify3 = Sm2Util.verify(m, signToStr, keyPair.getPublicKeyStr());
    // boolean verify4 = Sm2Util.verify(bytes, sign, keyPair.getPublicKeyStr());
    // System.out.println("验签: " + verify);
    // System.out.println("验签: " + verify2);
    // System.out.println("验签: " + verify3);
    // System.out.println("验签: " + verify4);
    //
    // currentTimeMillis = System.currentTimeMillis();
    // for (int i = 0; i < size; i++) {
    // signature = Sm2Util.sign(m, keyPair.getPrivateKeyStr());
    // verify2 = Sm2Util.verify(m, signature, keyPair.getPublicKeyStr());
    // if (!verify2) {
    // System.out.println(verify2);
    // }
    // }
    // currentTimeMillis2 = System.currentTimeMillis();
    // System.out.println(currentTimeMillis2 - currentTimeMillis);
    // }

}